import React, { useState, useRef, useEffect } from 'react';

/**
 * useRef Hook示例组件
 * 
 * 这个组件展示了React useRef Hook的多种使用场景：
 * 1. 引用DOM元素
 * 2. 保存可变值（不会触发重新渲染）
 * 3. 保存前一个状态值
 * 4. 实现命令式动画
 * 5. 计时器引用管理
 */
function UseRefExample() {
  // 状态
  const [inputValue, setInputValue] = useState('');
  const [count, setCount] = useState(0);
  const [isRunning, setIsRunning] = useState(false);
  
  // Ref示例1: 引用DOM元素
  const inputRef = useRef(null);
  
  // Ref示例2: 保存可变值（不会触发重新渲染）
  const renderCountRef = useRef(0);
  
  // Ref示例3: 保存前一个状态值
  const prevCountRef = useRef();
  
  // Ref示例4: 用于动画的元素引用
  const boxRef = useRef(null);
  
  // Ref示例5: 保存定时器ID
  const timerRef = useRef(null);
  const timerCountRef = useRef(0);
  
  // 跟踪渲染次数
  useEffect(() => {
    renderCountRef.current += 1;
  });
  
  // 保存前一个count值
  useEffect(() => {
    prevCountRef.current = count;
  }, [count]);
  
  // 聚焦输入框
  const focusInput = () => {
    // 使用ref直接访问DOM元素
    inputRef.current.focus();
  };
  
  // 处理输入变化
  const handleInputChange = (e) => {
    setInputValue(e.target.value);
  };
  
  // 执行动画
  const animateBox = () => {
    if (boxRef.current) {
      // 重置位置
      boxRef.current.style.transform = 'translateX(0)';
      boxRef.current.style.transition = 'none';
      
      // 强制重排
      void boxRef.current.offsetWidth;
      
      // 设置动画
      boxRef.current.style.transform = 'translateX(200px)';
      boxRef.current.style.transition = 'transform 1s ease-in-out';
    }
  };
  
  // 开始/停止计时器
  const toggleTimer = () => {
    if (isRunning) {
      // 停止计时器
      clearInterval(timerRef.current);
      timerRef.current = null;
    } else {
      // 开始计时器
      timerRef.current = setInterval(() => {
        timerCountRef.current += 1;
        // 注意：更新ref不会触发重新渲染，所以我们需要手动更新状态
        setCount(timerCountRef.current);
      }, 1000);
    }
    setIsRunning(!isRunning);
  };
  
  // 组件卸载时清理计时器
  useEffect(() => {
    return () => {
      if (timerRef.current) {
        clearInterval(timerRef.current);
      }
    };
  }, []);
  
  return (
    <div className="hook-example">
      <h2>useRef Hook 示例</h2>
      
      {/* 示例1: 引用DOM元素 */}
      <section>
        <h3>1. 引用DOM元素</h3>
        <div className="input-focus-example">
          <input
            ref={inputRef}
            type="text"
            value={inputValue}
            onChange={handleInputChange}
            placeholder="点击按钮聚焦此输入框"
          />
          <button onClick={focusInput}>聚焦输入框</button>
        </div>
        <p>当前输入值: {inputValue}</p>
      </section>
      
      {/* 示例2: 保存可变值 */}
      <section>
        <h3>2. 保存可变值（不触发重新渲染）</h3>
        <p>组件渲染次数: {renderCountRef.current}</p>
        <button onClick={() => setCount(count + 1)}>
          增加计数 (触发重新渲染)
        </button>
      </section>
      
      {/* 示例3: 保存前一个状态值 */}
      <section>
        <h3>3. 保存前一个状态值</h3>
        <p>当前计数: {count}</p>
        <p>前一个计数: {prevCountRef.current}</p>
        <button onClick={() => setCount(count + 1)}>增加计数</button>
      </section>
      
      {/* 示例4: 实现命令式动画 */}
      <section>
        <h3>4. 实现命令式动画</h3>
        <div className="animation-container">
          <div 
            ref={boxRef} 
            className="animated-box"
            style={{
              width: '50px',
              height: '50px',
              backgroundColor: 'blue',
              marginBottom: '10px'
            }}
          ></div>
          <button onClick={animateBox}>运行动画</button>
        </div>
      </section>
      
      {/* 示例5: 计时器引用管理 */}
      <section>
        <h3>5. 计时器引用管理</h3>
        <p>计时器计数: {count}</p>
        <button onClick={toggleTimer}>
          {isRunning ? '停止' : '开始'} 计时器
        </button>
        <p className="note">
          注意: 即使在组件重新渲染时，计时器也会继续运行，因为它的引用保存在useRef中
        </p>
      </section>
      
      <div className="explanation">
        <h3>useRef Hook 说明:</h3>
        <ul>
          <li><code>const refContainer = useRef(initialValue)</code> - 创建一个ref对象</li>
          <li>访问ref的当前值: <code>refContainer.current</code></li>
          <li>ref的值在组件的整个生命周期内保持不变</li>
          <li>修改ref的值不会触发组件重新渲染</li>
          <li>常见用例: 访问DOM元素、保存前一个值、保存不需要触发重新渲染的可变值</li>
          <li>与useState的区别: useRef不会触发重新渲染，而useState会</li>
        </ul>
      </div>
    </div>
  );
}

export default UseRefExample;